package shared;
import javax.media.opengl.GL2;

public class GLT
{
	// For best results, put this in a display list
	// Draw a torus (doughnut)  at z = fZVal... torus is in xy plane
	public static void drawTorus(GL2 gl2, float majorRadius, float minorRadius, int numMajor, int numMinor)
	{
		float vNormal[] = new float[3];
		double majorStep = 2.0f * Math.PI / numMajor;
		double minorStep = 2.0f * Math.PI / numMinor;
		int i, j;
		
		for(i = 0; i < numMajor; ++i)
		{
			double a0 = i * majorStep;
			double a1 = a0 + majorStep;
			float x0 = (float)Math.cos(a0);
			float y0 = (float)Math.sin(a0);
			float x1 = (float)Math.cos(a1);
			float y1 = (float)Math.sin(a1);
			
			gl2.glBegin(GL2.GL_TRIANGLE_STRIP);
			for(j = 0; j <= numMinor; ++j)
			{
				double b = j * minorStep;
				float c = (float)Math.cos(b);
				float r = minorRadius * c + majorRadius;
				float z = minorRadius * (float)Math.sin(b);
				
				// First point
				gl2.glTexCoord2f((float)i / (float)numMajor, (float)j / (float)numMinor);
				vNormal[0] = x0 * c;
				vNormal[1] = y0 * c;
				vNormal[2] = z / minorRadius;
				M3D.normalizeVector(vNormal);
				gl2.glNormal3fv(vNormal, 0);
				gl2.glVertex3f(x0 * r, y0 * r, z);
				
				gl2.glTexCoord2f((float)(i + 1) / (float)numMajor, (float)j / (float)numMinor);
				vNormal[0] = x1 * c;
				vNormal[1] = y1 * c;
				vNormal[2] = z / minorRadius;
				M3D.normalizeVector(vNormal);
				gl2.glNormal3fv(vNormal, 0);
				gl2.glVertex3f(x1 * r, y1 * r, z);
			}
			
			gl2.glEnd();
		}
	}
	
	// For best results, put this in a display list
	// Draw a sphere at the origin
	public static void drawSphere(GL2 gl2, float fRadius, int iSlices, int iStacks)
	{
		float drho = 3.141592653589f / (float)iStacks;
		float dtheta = 2.0f * 3.141592653589f / (float)iSlices;
		float ds = 1.0f / (float)iSlices;
		float dt = 1.0f / (float)iStacks;
		float t = 1.0f;
		float s = 0.0f;
		int i, j; // Looping variables
		
		for(i = 0; i < iStacks; i++)
		{
			float rho = (float)i * drho;
			float srho = (float)Math.sin(rho);
			float crho = (float)Math.cos(rho);
			float srhodrho = (float)Math.sin(rho + drho);
			float crhodrho = (float)Math.cos(rho + drho);
			
			// Many sources of OpenGL sphere drawing code uses a triangle fan
	        // for the caps of the sphere. This however introduces texturing 
	        // artifacts at the poles on some OpenGL implementations
			gl2.glBegin(GL2.GL_TRIANGLE_STRIP);
			s = 0.0f;
			for(j = 0; j <= iSlices; j++)
			{
				float theta = (j == iSlices) ? 0.0f : j * dtheta;
				float stheta = (float)-Math.sin(theta);
				float ctheta = (float)-Math.cos(theta);
				
				float x = stheta * srho;
				float y = ctheta * srho;
				float z = crho;
				
				gl2.glTexCoord2f(s, t);
				gl2.glNormal3f(x, y, z);
				gl2.glVertex3f(x * fRadius, y * fRadius, z * fRadius);
				
				x = stheta * srhodrho;
				y = ctheta * srhodrho;
				z = crhodrho;
				gl2.glTexCoord2f(s, t - dt);
				s += ds;
				gl2.glNormal3f(x, y, z);
				gl2.glVertex3f(x * fRadius, y * fRadius, z * fRadius);
			}
			gl2.glEnd();
			
			t -= dt;
		}
	}
}
